package com.zhw.client;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.extern.slf4j.Slf4j;

/**
 * @author weizhang52
 * @description:  netty客户端启动类：向服务端发送消息，接收服务端发送的消息
 * https://cloud.tencent.com/developer/article/1360553
 * @date 2019/4/16
 * @modify
 */
@Slf4j
public class HelloNettyClient {

    // 要请求的服务器的ip地址
    private String ip;
    // 服务器的端口
    private int port;

    // 请求端主题
    public static void start() {

        EventLoopGroup bossGroup = new NioEventLoopGroup();

        Bootstrap bs = new Bootstrap();

        bs.group(bossGroup)
                .channel(NioSocketChannel.class)
                .option(ChannelOption.SO_KEEPALIVE, true)
                .handler(new ChannelInitializer<SocketChannel>() {
                    /**
                     * ChannelInboundHandler用来接收消息。Netty提供ChannelInitializer用来配置Handler， ChannelInitializer通过ChannelPipeline
                     * 来添加ChannelHandler。ChannelInitializer自身也是一个ChannelHandler，再添加完所有handlers之后会自动从ChannelPipeline中删除自己。
                     */
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        // marshalling 序列化对象的解码
//                  socketChannel.pipeline().addLast(MarshallingCodefactory.buildDecoder());
                        // marshalling 序列化对象的编码
//                  socketChannel.pipeline().addLast(MarshallingCodefactory.buildEncoder());

                        // 处理来自服务端的响应信息:ChannelHandler的执行顺序与向ChannelPipeline添加时的顺序有关
                        ChannelPipeline p = socketChannel.pipeline();
                        p.addLast(new HelloNettyClientHandler());
                    }
                });

        // 客户端开启
        ChannelFuture cf = null;
        try {
            cf = bs.connect("127.0.0.1", 17777);
//            cf.addListener(new ReConnectHandler());
            String reqStr = "我是客户端请求1$_";
            cf.channel().writeAndFlush(reqStr);
            log.info("[HelloNettyClient] 已发送请求");
        } catch (Exception e) {
            log.info("[HelloNettyClient] 已发送请求出错");
            e.printStackTrace();
        }


//        String reqStr = "我是客户端请求1$_";
        // 发送客户端的请求
//        cf.channel().writeAndFlush(Unpooled.copiedBuffer(reqStr.getBytes(Constant.charset)));

//        cf.channel().writeAndFlush(reqStr);
//        log.info("[HelloNettyClient] 已发送请求");
//      Thread.sleep(300);
//      cf.channel().writeAndFlush(Unpooled.copiedBuffer("我是客户端请求2$_---".getBytes(Constant.charset)));
//      Thread.sleep(300);
//      cf.channel().writeAndFlush(Unpooled.copiedBuffer("我是客户端请求3$_".getBytes(Constant.charset)));

//      Student student = new Student();
//      student.setId(3);
//      student.setName("张三");
//      cf.channel().writeAndFlush(student);

        // 等待直到连接中断
        try {
            cf.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            log.info("[] 连接中断");
            e.printStackTrace();
        }

    }

    public static void main(String[] args) {

        log.info("[HelloNettyClient] 开始启动客户端");
        HelloNettyClient.start();

    }

}
